home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 2 / Gold Medal Software Volume 2 (Gold Medal) (1994).iso / prog / asm_0_m.arj / EGA720.ASM < prev    next >
Assembly Source File  |  1986-06-28  |  14KB  |  398 lines

  1. page    60,132
  2. title   Ega720      Hercules-compatible resident driver for EGA cards
  3.  
  4. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  5. ; This program demonstrates how to program an Enhanced Graphics Adapter driving
  6. ; a Monochrome display in a Hercules-compatible 720x348 mode.  It will work
  7. ; with *any* EGA card with at least 128K memory.  It does not require an
  8. ; EGA clones with built-in Hercules emulation.  However, it will NOT work if
  9. ; you have a CGA installed in addition to the EGA.
  10. ;
  11. ; You can run this as a "stay resident" program, and patch existing Hercules-
  12. ; compatible programs to call it so they can run on an EGA in graphics mode.
  13. ; (Or similarly, patch a program that does know about the EGA to run in the
  14. ; higher 720x348 resolution instead of the normal 640x350 EGA resolution, by
  15. ; using its Hercules driver instead of its EGA driver.)
  16. ;
  17. ; Or, you can incorporate this code into your own program to provide a higher
  18. ; resolution mode on Monochrome EGA's.  In this case, ignore all the details
  19. ; about how to patch existing programs and look at the "DoInt" subroutine and
  20. ; the "HOW IT WORKS" discussion.
  21. ;
  22. ; The program does not make the EGA register-compatible with the Hercules,
  23. ; however it does give the same memory map and 720 pixel wide display as the
  24. ; Hercules card.  To make an existing Hercules program work with this program,
  25. ; you will have to patch that program so that its initialization code calls
  26. ; this routine instead of loading the Hercules registers.  Once the card is
  27. ; initialized, the program can write to the display buffer just as if it were
  28. ; writing to a Hercules card.
  29. ;
  30. ; ***HOW TO INSTALL THIS PROGRAM***
  31. ;
  32. ; Assemble, link, and exe2bin this file.  Then run it.  It installs a routine
  33. ; under Interrupt 68h (normally unused).  If INT 68h is in use for something
  34. ; else on your system, change the interrupt number below.
  35. ;
  36. ; ***HOW TO PATCH AN EXISTING PROGRAM***
  37. ;
  38. ; To patch an existing Hercules-compatible program, you will need to use
  39. ; DEBUG to: 1) find the Hercules initialization code, 2) determine whether it
  40. ; uses Hercules Page 0, Page 1, or both, and 3) patch in an appropriate INT 68h
  41. ; call.
  42. ;
  43. ; Hercules initialization code will consist of some OUT instructions to these
  44. ; registers: 3BFh, 3B8h, 3B4h, and 3B5h.  The sequence will be something like:
  45. ;
  46. ; Output the value 1 or 3 to 3BFh (this may be omitted in older programs)
  47. ; Output any value with bit 3 off to 3B8h (turns video off)
  48. ; A loop writing various values to 3B4h and 3B5h (loads CRTC registers)
  49. ; Output a value with bit 3 on to 3B8h (turns video back on)
  50. ;
  51. ; * This last output gives you some critical information.  Look at the values
  52. ;   of bits 1 and 7 in particular:
  53. ;       Bit 1 (mask 02h): 0 = text mode, 1 = graphics mode.
  54. ;       Bit 7 (mask 80h): 0 = page 0, 1 = page 1.
  55. ;
  56. ; To find the code, you can use the Search command in DEBUG something like:
  57. ;
  58. ;       -s 100 l xxxx bf 3
  59. ; or
  60. ;       -s 100 l xxxx b8 3
  61. ;
  62. ; where xxxx is the value in register CX.  If the program has a separate
  63. ; Hercules driver, that's the file you should be looking in.  If not, try
  64. ; the program file itself (if a .EXE file do the usual trick of renaming it
  65. ; to a different extension, because you will need to write it back out.)
  66. ;
  67. ; If the initialization sequence is setting TEXT mode, replace it with a
  68. ; normal BIOS "set mode" call.
  69. ;
  70. ;       mov     ah,0                    ; (You're in DEBUG, so hex is default)
  71. ;       mov     al,7                    ; (Yes, this could just be a MOV AX)
  72. ;       int     10
  73. ;
  74. ; You may find code that loads the Hercules registers and then also does a
  75. ; BIOS set mode call.  In that case, just patch out the Hercules code and
  76. ; let the set mode do its thing.  Or there may just be a BIOS call.  Leave
  77. ; it alone.
  78. ;
  79. ; If the initialization sequence is setting GRAPHICS mode, replace it with
  80. ; a call to this resident routine:
  81. ;
  82. ;       mov     al,80 *or* 00           ; 80 for page 1, 00 for page 0
  83. ;       int     68
  84. ;
  85. ; Use 80 or 00 depending on whether you found the initialization code to be
  86. ; using page 1 or page 0.  For example, Microsoft Windows uses page 1, while
  87. ; Framework version 1 uses page 0.
  88. ;
  89. ; Naturally, when making these patches you should look at the surrounding code
  90. ; to duplicate any register saving, return values, NEAR or FAR return, etc.
  91. ; Note that the INT 10 and INT 68 calls preserve all registers except AX.
  92. ;
  93. ; These patches will be sufficient for many programs.  If you have a program
  94. ; that uses both Hercules pages 0 and 1 and flips back and forth between them,
  95. ; you will need to do some additional work.  The program will contain
  96. ; additional output instructions to port 3B8, with bit 7 (mask 80h) on or off.
  97. ; Replace these with:
  98. ;
  99. ;       mov     al,81 *or* 01           ; 81 for page 1, 01 for page 0
  100. ;       int     68
  101. ;
  102. ; *Note* I haven't tested this option, sorry.
  103. ;
  104. ; ***A SAMPLE PATCH - MICROSOFT WINDOWS***
  105. ;
  106. ; To patch Microsoft Windows for this high resolution mode, do the following:
  107. ; (This is for Windows version 1.01, either the retail or Developer's version)
  108. ;
  109. ;   1.  **Make COPIES of your SETUP and BUILD disks**
  110. ;       **Use the COPIES.  DO NOT MODIFY YOUR ORIGINALS!!**
  111. ;
  112. ;   2.  On your SETUP disk, apply this patch:
  113. ;
  114. ;           A>debug hercules.drv
  115. ;           -a a97
  116. ;           xxxx:0A97 mov al,80
  117. ;           xxxx:0A99 int 68
  118. ;           xxxx:0A9B mov al,1
  119. ;           xxxx:0A9D ret
  120. ;           xxxx:0A9E
  121. ;           -a ab2
  122. ;           xxxx:0AB2 mov ah,0
  123. ;           xxxx:0AB4 int 10
  124. ;           xxxx:0AB6 mov al,1
  125. ;           xxxx:0AB8 ret
  126. ;           xxxx:0AB9
  127. ;           -w
  128. ;           -q
  129. ;
  130. ;   3.  On your BUILD disk, apply this patch:
  131. ;
  132. ;           A>copy egamono.grb hercules.grb
  133. ;
  134. ;           A>debug hercules.lgo
  135. ;           -a 343
  136. ;           xxxx:0343 mov al,80
  137. ;           xxxx:0345 int 68
  138. ;           xxxx:0347 ret
  139. ;           xxxx:0348
  140. ;           -w
  141. ;           -q
  142. ;
  143. ;   4.  Run SETUP to install Windows.  When it asks for the display type,
  144. ;       specify Hercules.
  145. ;
  146. ; You should be up and running in the higher resolution mode!
  147. ; The only problem I have found is that if you run an "old" application
  148. ; that takes over the screen it doesn't display the "press any key to
  149. ; return to Windows" message.  This is done by HERCULES.GRB, which I didn't
  150. ; get patched, but instead took the shortcut of copying EGAMONO.GRB.
  151. ;
  152. ; NOTE: Microsoft has OK'd my uploading this patch (see BIX message
  153. ; microsoft/applications #192), but of course does not endorse or take
  154. ; any responsibility for it.  Thank you Microsoft for a sensible attitude.
  155. ;
  156. ; I have also successfully patched Lotus 1-2-3 to run on the EGA in
  157. ; this mode, but will NOT make that patch available because Lotus is very
  158. ; unfriendly to people who patch their products.  See BIX message
  159. ; spreadsheets/other #24.  The words I have for Lotus are not printable.
  160. ;
  161. ; (I have also patched Framework version 1.1 but haven't yet checked with
  162. ; Ashton-Tate about uploading patches.  Hint:  It's HERCULES.DRV, and they
  163. ; use page 0, unlike Windows which uses page 1.)
  164. ;
  165. ; ***HOW IT WORKS***
  166. ;
  167. ; If you want to support the 720x348 mode in a program of your own, this is
  168. ; the section of interest to you.  (Or you can ignore this and just use the
  169. ; code.)
  170. ;
  171. ; This program uses some EGA features which are not used in the standard modes.
  172. ; Page number references are from the August 2, 1984 EGA manual.
  173. ;
  174. ; The "Memory Map" bits in Graphics Controller register 6 ("Miscellaneous
  175. ; Register") are set to 00.  This maps the EGA display memory into a full
  176. ; 128K bytes from A0000h to BFFFFh.  This is why you can't have a CGA in
  177. ; the same machine.  Theoretically, you could set these to 10 if you were
  178. ; using Hercules page 0 (B0000-B7FFF) and then you could co-exist with a CGA.
  179. ; I didn't get this to work, however.  (p.53)
  180. ;
  181. ; In this 128K mode (only), bit 5 of the Miscellaneous Output Register selects
  182. ; which 64K block is displayed.  This is described wrong in the manual.  All
  183. ; standard modes set this to 1.  We set it to 0, which selects the higher
  184. ; 64K block (B0000-BFFFF).  1 would give us A0000-AFFFF.  (p.13)
  185. ;
  186. ; Like in the standard modes, we then use CRTC registers 0C/0D (Start Address)
  187. ; to select the display base address within that 64K block.  This selects
  188. ; Hercules page 0 or 1.  (p.34)
  189. ;
  190. ; The "native" EGA graphics modes use linear addressing, where each scan line
  191. ; begins in memory right after the previous one.  The CGA has a strange
  192. ; interleaving, where alternate rows are offset by 2000h.  The Hercules card
  193. ; is like the CGA except it uses groups of four rows instead of two.  So your
  194. ; row addressing is like this:
  195. ;   Row 0:  0000h
  196. ;   Row 1:  2000h
  197. ;   Row 2:  4000h
  198. ;   Row 3:  6000h
  199. ;   Row 4:  0000h + (size of one row = 90 bytes)
  200. ;   Row 5:  2000h + 90
  201. ;   etc.
  202. ;
  203. ; CRTC register 17h (Mode Control) contains two bits (bits 0 and 1) which
  204. ; control this addressing.  In the EGA native modes, these bits are both 1,
  205. ; and addressing is linear.  If bit 0 is 0, you get the CGA compatibility
  206. ; mode, with alternating lines offset by 2000h.  If bits 0 and 1 are both 0,
  207. ; you get the Hercules addressing mode as shown above.  Don't be misled by
  208. ; the funny name of bit 1 in the manual.  It should have been called CMS 1
  209. ; because it is exactly like bit 0 (CMS 0).  (p.41-42)
  210. ;
  211. ; If you are writing your own software to support the 720 mode, you may find
  212. ; it easier to use linear addressing instead of the funny Hercules/CGA style
  213. ; addressing.  To do this, set both these bits to 1 instead of 0.  Fiddle
  214. ; with the CRTC registers a little and you will then get a 720x350 mode.
  215. ; (Hercules is 348 because it had to be divisible by 4.)  I haven't tested
  216. ; this, however.
  217. ;
  218. ; ***NO NONSENSE PUBLIC DOMAIN STATEMENT***
  219. ;
  220. ; This program and documentation are placed in the public domain.  Period.
  221. ;
  222. ; June 22, 1986
  223. ;
  224. ; Michael Geary
  225. ; P.O. Box 1479
  226. ; Los Gatos, CA  95031
  227. ; BIX: geary
  228.  
  229. HercInt equ     68h                     ; Interrupt to put EGA in Hercules mode
  230.                                         ; Change this if INT 68h conflicts
  231.                                         ; with something else
  232.  
  233. Code    SEGMENT
  234.  
  235.  
  236. Zseg    SEGMENT at 0
  237.  
  238.         org     HercInt*4               ; Our interrupt vector
  239. IntOff  dw      ?
  240. IntSeg  dw      ?
  241.  
  242.         org     4A8h                    ; EGA BIOS "Save Table" pointer
  243. SvXoff  dw      ?
  244. SvXseg  dw      ?
  245.  
  246. Zseg    ENDS
  247.  
  248.  
  249. Data    SEGMENT byte
  250.  
  251. ; This is a "Save Table" as used by the EGA BIOS.  Since it is just used
  252. ; temporarily for our mode setting, we provide only the single parameter
  253. ; table instead of the full set.
  254.  
  255. Table   label   dword
  256.         dw      offset Com:Params - (11h*40h)
  257. TblSeg  dw      ?
  258.         dd      7 dup (?)
  259.  
  260. Params  label   byte
  261.  
  262. ; "Hercules" Mode F (large memory)
  263.  
  264.         ; cols, rows, lines
  265.         db      05Ah, 018h, 00Eh
  266.  
  267.         ; page len
  268.         dw      08000h
  269.  
  270.         ; sequencer
  271.         db      001h, 001h, 000h, 006h
  272.  
  273.         ; miscoutreg
  274.         db      086h
  275.  
  276.         ; crtc
  277.         db      06Ch, 059h, 05Ch, 02Ch
  278.         db      05Bh, 04Ch, 070h, 01Fh
  279.         db      000h, 003h, 000h, 000h
  280. PageBit label   byte
  281.         db      000h, 000h, 000h, 000h
  282.         db      05Dh, 02Dh, 05Bh, 02Dh
  283.         db      00Dh, 05Ch, 06Ch, 0E0h, 0FFh
  284.  
  285.         ; attribute
  286.         db      000h, 008h, 008h, 008h, 008h, 008h, 008h, 008h
  287.         db      008h, 008h, 008h, 008h, 008h, 008h, 008h, 008h
  288.         db      003h, 000h, 001h, 000h
  289.  
  290.         ; graphics
  291.         db      000h, 000h, 000h, 000h, 000h, 000h, 001h, 00Fh, 0FFh
  292.  
  293. Data    ENDS
  294.  
  295.  
  296. Com     GROUP   Code, Data, Top
  297.  
  298.         ASSUME  cs:Com, ds:Com, es:nothing, ss:nothing
  299.  
  300.         org     100h
  301.  
  302. ; This is the code to install the resident driver.  You won't need it if you
  303. ; are incorporating the 720 technique into your own program, of course.
  304.  
  305. Start:
  306.         xor     ax, ax
  307.         mov     es, ax
  308.         ASSUME  es:Zseg
  309.  
  310.         CLI
  311.  
  312.         mov     IntOff, offset Com:DoInt
  313.         mov     IntSeg, cs
  314.  
  315.         mov     TblSeg, cs
  316.  
  317.         STI
  318.  
  319.         mov     dx, offset Com:TopOff
  320.         shr     dx, 1
  321.         shr     dx, 1
  322.         shr     dx, 1
  323.         shr     dx, 1
  324.  
  325.         mov     ax, 3100h
  326.         int     21h                         ; Terminate and stay resident
  327.  
  328.         ASSUME  ds:nothing
  329.  
  330. ; This the code to set up the 720x348 mode.  To make life easy, we
  331. ; temporarily set up a pointer to our register table and then let the BIOS
  332. ; do the work of loading all the registers.
  333.  
  334. DoInt:
  335.         push    es
  336.         push    ax
  337.  
  338.         test    al, 1                   ; is it just a page flip?
  339.         jnz     Flip                    ; yes, just go do that
  340.  
  341. ; Set up Hercules mode from scratch
  342.         and     al, 80h
  343.         mov     PageBit, al             ; set page 0 or 1
  344.  
  345.         xor     ax, ax
  346.         mov     es, ax
  347.         ASSUME  es:Zseg
  348.  
  349.         CLI
  350.  
  351.         push    SvXoff                  ; save previous parameter table
  352.         push    SvXseg
  353.  
  354.         mov     SvXoff, offset Com:Table    ; temporarily set to our table
  355.         mov     SvXseg, cs
  356.  
  357.         STI
  358.  
  359.         mov     ax, 000Fh               ; call BIOS to do the mode setting
  360.         int     10h                     ; using our parameters
  361.  
  362.         CLI
  363.  
  364.         pop     SvXseg                  ; restore previous parameter table
  365.         pop     SvXoff
  366.  
  367.         STI
  368.  
  369. return:
  370.         pop     ax
  371.         pop     es
  372.  
  373.         iret
  374.  
  375. ; Do a simple page flip.  *Note*  I haven't tested this!  -MG
  376. ; If you are using the 720 technique in your own program you probably won't
  377. ; want to use this code anyway.
  378. Flip:
  379.         and     al, 80h
  380.         push    dx
  381.         mov     dx, 3B4h
  382.         mov     ah, al
  383.         mov     al, 0Ch
  384.         out     dx, ax
  385.         pop     dx
  386.         jmp short return
  387.  
  388.  
  389. Code    ENDS
  390.  
  391.  
  392. Top     SEGMENT para
  393. TopOff:
  394. Top     ENDS
  395.  
  396.  
  397.         END     Start
  398.